package com.mlink.ai.chat.utils

import android.app.Service
import android.content.Context
import android.media.MediaDrm
import android.os.Build
import android.provider.Settings
import android.telephony.TelephonyManager
import android.util.Base64
import com.cipher.CipherUtils.getMD5
import com.mlink.ai.chat.AiChatApplication
import com.tencent.mmkv.MMKV
import java.util.UUID

object DeviceUtils {

    const val PREF_FIREBASE_INSTALLATIONS_ID = "pref_firebase_installations_id"

    fun getUid(): String {
        var uid = MMKV.defaultMMKV().decodeString((PREF_FIREBASE_INSTALLATIONS_ID))
        if (uid != null) return uid
        uid = when (Build.VERSION.SDK_INT) {
            Build.VERSION_CODES.LOLLIPOP -> getDeviceId(AiChatApplication.app)
            in Build.VERSION_CODES.LOLLIPOP_MR1 until Build.VERSION_CODES.O -> getPsuedoId()
            else -> getSsaIdAndDrmId(AiChatApplication.app)
        }
        if (uid.isNullOrEmpty()) uid = UUID.randomUUID().toString()
        // 转为32个16进制字符进行存储
        val uidNew = getMD5(uid.toByteArray())
        return uidNew ?: ""
    }

    /**
     * 获取 DeviceId，属于硬件信息，恢复出厂设置也不会发生改变
     */
    private fun getDeviceId(context: Context): String? = try {
        (context.getSystemService(Service.TELEPHONY_SERVICE) as TelephonyManager).deviceId
    } catch (_: Exception) {
        null
    }

    /**
     * 硬件信息和 DRM ID 进行拼接
     */
    private fun getPsuedoId(): String? =
        try {
            val devId = "35" +
                    Build.BOARD.length % 10 + // 主板
                    Build.BRAND.length % 10 + // android 系统定制商
                    Build.CPU_ABI.length % 10 + // cpu 指令集
                    Build.DEVICE.length % 10 + // 设备参数
                    Build.DISPLAY.length % 10 + // 显示屏参数
                    Build.HOST.length % 10 +
                    Build.ID.length % 10 + // 修订版本列表
                    Build.MANUFACTURER.length % 10 + // 硬件制造商
                    Build.MODEL.length % 10 + // 版本
                    Build.PRODUCT.length % 10 + // 手机制造商
                    Build.TAGS.length % 10 + // 描述 build 的标签
                    Build.TYPE.length % 10 + // builder 类型
                    Build.USER.length % 10 //13 位

            //A hardware serial number, if available. Alphanumeric only, case-insensitive.
            val drmId = getDrmId()
            //使用硬件信息拼凑出来的15位号码
            UUID(devId.hashCode().toLong(), drmId.hashCode().toLong()).toString()
        } catch (e: Exception) {
            null
        }

    /**
     * DRM id 是使用 DRM API 中的 MediaDrm，它的作用是来获取用于解密受保护的媒体流的密钥，同时是 Google 中推荐的方法。
     */
    private fun getDrmId(): String? = try {
        val wideVineUuid = UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L)
        val wvDrm = MediaDrm(wideVineUuid)
        val wideVineId: ByteArray = wvDrm.getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID)
        Base64.encodeToString(wideVineId, Base64.NO_WRAP)
    } catch (e: Exception) {
        null
    }

    /**
     * SsaId 和 DRM ID 进行组合，确保稳定性
     */
    private fun getSsaIdAndDrmId(context: Context): String? = try {
        UUID(getSsaId(context).hashCode().toLong(), getDrmId().hashCode().toLong()).toString()
    } catch (e: Exception) {
        null
    }

    /**
     * SSAID 即 Android_ID
     * 在恢复出厂设置后会发生改变，同时 SSAID 还存在一个已知的 bug，不同的设备可能会产生相同的 ID: 9774d56d682e549c。
     * 所以他的稳定性和唯一性都存在问题。
     */
    private fun getSsaId(context: Context): String? =
        Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)

}